import axios from "axios";
import FormData from "form-data";
import { session } from "electron";
import HmacSHA256 from "crypto-js/hmac-sha256";
import MD5 from "crypto-js/md5";
import Base64 from "crypto-js/enc-base64";

const biliKey = "xkukMulDfzDXJorEvdNeFPSa",
  bibiSecret = "nNdxjopnibiaqdiDhBovtKoWFMQLbu";
function authBiliHeaders(params = "") {
  const t = new Date().getTime();
  const md5data = MD5(params);
  const heardsMap = {
    "x-bili-timestamp": `${t}`,
    "x-bili-signature-method": "HMAC-SHA256",
    "x-bili-signature-nonce": `${t + parseInt(Math.random() * 100000 + "")}`,
    "x-bili-accesskeyid": biliKey,
    "x-bili-signature-version": "1.0",
    "x-bili-content-md5": md5data
  };
  const str = Object.keys(heardsMap)
    .sort()
    .reduce((acc, curr, idx) => {
      if (idx == 0) {
        return `${curr}:${heardsMap[curr]}`;
      } else {
        return `${acc}\n${curr}:${heardsMap[curr]}`;
      }
    }, "");
  const signature = HmacSHA256(str, bibiSecret);
  return {
    ...heardsMap,
    Authorization: signature
  };
}
const instance = axios.create({
  baseURL: "",
  responseType: "json",
  timeout: 5000,
  withCredentials: false,
  headers: {
    "Content-Type": "application/json",
    Accept: "application/json"
  },
  // proxy:{
  //   protocol: 'http',
  //   host: '127.0.0.1',
  //   port: 8888,
  // },
  transformResponse: data => {
    //console.log(data)
    return JSON.parse(data);
  }
});
instance.interceptors.request.use(
  async function (config) {
    const ses = session.defaultSession;
    const cookies = await ses.cookies.get({
      url: config.url
    });
    if (config.withCredentials && cookies.length > 0) {
      config.headers["Cookie"] = cookies.reduce((acc, curr) => {
        return (acc += `${curr.name}=${curr.value};`);
      }, "");
    }
    if (
      ["application/x-www-form-urlencoded"].includes(
        <string>config.headers["Content-Type"]
      )
    ) {
      const form = new FormData();
      for (let k in config.data) {
        if (typeof config.data[k] !== "object") {
          form.append(k, config.data[k]);
        }
      }
      config.data = form;
      Object.assign(config.headers, form.getHeaders());
    }
    if (config.biliAuth) {
      Object.assign(
        config.headers,
        authBiliHeaders(JSON.stringify(config.data))
      );
    }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);

instance.interceptors.response.use(
  function (response) {
    const ses = session.defaultSession;
    if (response.headers["set-cookie"]) {
      response.headers["set-cookie"].forEach(item => {
        const arr = item.split(";").map(v => {
          return v.trim().split("=");
        });
        const o: any = {
          url: response.config.url,
          name: arr[0][0],
          value: arr[0][1],
          domain: arr.find(v => v[0] == "Domain")?.[1] ?? "",
          path: arr.find(v => v[0] == "Path")?.[1] ?? "/",
          secure: false,
          httpOnly: false,
          sameSite: "lax"
        };
        if (arr.find(v => v[0] == "Expires")) {
          o.expirationDate =
            new Date(arr.find(v => v[0] == "Expires")?.[1]).getTime() / 1e3;
        }
        ses.cookies.set(o);
      });
    }
    return Promise.resolve(response.data);
  },
  async function (error) {
    return Promise.reject(error);
  }
);

export default instance;
